﻿// PETest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <windows.h>
#include <commctrl.h>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <dbghelp.h>
#include "PEFile.h"
#include "COFFFile.h"
#include "AnonObjFile.h"
#include "ArchiveFile.h"
#include "resource.h"

#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "dbghelp.lib")

// 确保包含列表视图控件的定义
#ifndef LVS_GRIDLINES
#define LVS_GRIDLINES 0x00000040
#endif

// 窗口控件ID
#define ID_TREEVIEW 1001
#define ID_EDIT 1002
#define ID_FILE_OPEN 1003
#define ID_LISTVIEW 1004
#define ID_PEINFO_LISTVIEW 1005
#define ID_EXPORT_LISTVIEW 1006
#define ID_DEPENDENCY_LISTVIEW 1007  // 新增依赖库列表控件ID
#define ID_EXPORT_MENU 1008
#define ID_EXPORT_UNDECORATE 1009
#define ID_EXPORT_DECORATE 1010
#define ID_EXPORT_SEARCH 1011
#define ID_IMPORT_SEARCH 1012

// 图标ID
#define IDI_ICON_APP 101
#define IDI_ICON_FILE 102
#define IDI_ICON_PE 103
#define IDI_ICON_EXPORT 104
#define IDI_ICON_IMPORT 105

struct MappingFileInfo
{
	HANDLE hFile;
	HANDLE hMapping;
	PVOID  pData;
	DWORD  dwFileSize;
};

struct ExportItem {
	std::wstring originalName;
	std::wstring decoratedName;
	bool isDecorated;
};

// 全局变量
HWND g_hTreeView = NULL;
HWND g_hEdit = NULL;
HWND g_hListView = NULL;
HWND g_hPEInfoListView = NULL;
HWND g_hExportListView = NULL;
HWND g_hDependencyListView = NULL;  // 新增依赖库列表控件句柄
HWND g_hExportSearch = NULL;
HWND g_hImportSearch = NULL;
CPEFile* g_pPEFile = NULL;
MappingFileInfo g_stuMap = {0};  // 添加全局文件映射信息
std::vector<ExportItem> g_exportItems;

// 函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void InitTreeView(HWND hwndParent);
void DisplayPEInfo();
void DisplayExportTable();
void DisplayImportTable();
void DisplayDependencies();  // 新增函数声明
BOOL SearchDllFile(const WCHAR* szDllName, WCHAR* szFullPath, DWORD dwMaxPath);
void SearchExportTable(const WCHAR* szSearchText);
void SearchImportTable(const WCHAR* szSearchText);

BOOL MappingFile(const std::string& strFilePathName, MappingFileInfo& stuOut)
{
	HANDLE hFile = CreateFileA(strFilePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		DWORD dwErr = GetLastError();
		return FALSE;
	}

	HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (NULL == hMapping)
	{
		CloseHandle(hFile);
		return FALSE;
	}

	PVOID  pData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
	if (NULL == pData)
	{
		CloseHandle(hMapping);
		CloseHandle(hFile);
		DWORD dwErr = GetLastError();
		return FALSE;
	}

	GetFileSize(hFile, &stuOut.dwFileSize);

	stuOut.hFile = hFile;
	stuOut.hMapping = hMapping;
	stuOut.pData = pData;

	return TRUE;
}

BOOL UnMappingFile(MappingFileInfo& stuInfo)
{
	if (stuInfo.pData)
	{
		UnmapViewOfFile(stuInfo.pData);
		stuInfo.pData = NULL;
	}

	if (stuInfo.hMapping)
	{
		CloseHandle(stuInfo.hMapping);
		stuInfo.hMapping = NULL;
	}

	if (stuInfo.hFile)
	{
		CloseHandle(stuInfo.hFile);
		stuInfo.hFile = INVALID_HANDLE_VALUE;
	}
	return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	// 初始化通用控件
	INITCOMMONCONTROLSEX icex;
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	icex.dwICC = ICC_TREEVIEW_CLASSES | ICC_LISTVIEW_CLASSES | ICC_STANDARD_CLASSES;
	InitCommonControlsEx(&icex);

	// 注册窗口类
	WNDCLASSEX wcex = {0};
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.hInstance = hInstance;
	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszClassName = L"PETestClass";
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON_APP));
	wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON_APP));
	RegisterClassEx(&wcex);

	// 创建主窗口
	HWND hwnd = CreateWindow(L"PETestClass", L"PE文件分析器",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 1024, 768,
		nullptr, nullptr, hInstance, nullptr);

	if (!hwnd) return FALSE;

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// 消息循环
	MSG msg;
	while (GetMessage(&msg, nullptr, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_CREATE:
		InitTreeView(hwnd);
		break;

	case WM_SIZE:
	{
		// 获取窗口客户区大小
		RECT rcClient;
		GetClientRect(hwnd, &rcClient);
		int width = rcClient.right - rcClient.left;
		int height = rcClient.bottom - rcClient.top;

		// 设置树形控件大小
		SetWindowPos(g_hTreeView, NULL, 10, 10, 250, height - 20, SWP_NOZORDER);

		// 设置右侧控件大小
		int rightWidth = width - 270;  // 270 = 树形控件宽度(250) + 左边距(10) + 间距(10)
		int rightHeight = height - 20;  // 20 = 上下边距各10

		// 设置编辑控件大小
		SetWindowPos(g_hEdit, NULL, 270, 10, rightWidth, rightHeight, SWP_NOZORDER);

		// 调整搜索框和列表控件位置
		int searchHeight = 25;
		int listTop = 40;  // 搜索框下方

		// 设置搜索框大小
		SetWindowPos(g_hExportSearch, NULL, 270, 10, rightWidth, searchHeight, SWP_NOZORDER);
		SetWindowPos(g_hImportSearch, NULL, 270, 10, rightWidth, searchHeight, SWP_NOZORDER);

		// 设置列表控件大小
		SetWindowPos(g_hListView, NULL, 270, listTop, rightWidth, rightHeight - searchHeight - 10, SWP_NOZORDER);
		SetWindowPos(g_hPEInfoListView, NULL, 270, listTop, rightWidth, rightHeight - searchHeight - 10, SWP_NOZORDER);
		SetWindowPos(g_hExportListView, NULL, 270, listTop, rightWidth, rightHeight - searchHeight - 10, SWP_NOZORDER);
		SetWindowPos(g_hDependencyListView, NULL, 270, listTop, rightWidth, rightHeight - searchHeight - 10, SWP_NOZORDER);

		// 调整列表控件列宽
		// 导入表列宽
		ListView_SetColumnWidth(g_hListView, 0, rightWidth * 200 / 740);  // DLL名称
		ListView_SetColumnWidth(g_hListView, 1, rightWidth * 300 / 740);  // 函数名称
		ListView_SetColumnWidth(g_hListView, 2, rightWidth * 100 / 740);  // 序号

		// PE信息列宽
		ListView_SetColumnWidth(g_hPEInfoListView, 0, rightWidth * 250 / 740);  // 属性
		ListView_SetColumnWidth(g_hPEInfoListView, 1, rightWidth * 470 / 740);  // 值

		// 导出表列宽
		ListView_SetColumnWidth(g_hExportListView, 0, rightWidth * 150 / 740);  // 序号
		ListView_SetColumnWidth(g_hExportListView, 1, rightWidth * 570 / 740);  // 函数名称
	}
	break;

	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case ID_FILE_OPEN:
		{
			OPENFILENAME ofn = {0};
			WCHAR szFile[MAX_PATH] = {0};
			ofn.lStructSize = sizeof(ofn);
			ofn.hwndOwner = hwnd;
			ofn.lpstrFile = szFile;
			ofn.nMaxFile = sizeof(szFile);
			ofn.lpstrFilter = L"可执行文件\0*.exe\0动态链接库\0*.dll\0静态库\0*.lib\0所有支持的文件\0*.exe;*.dll;*.lib\0\0";
			ofn.nFilterIndex = 1;
			ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

			if (GetOpenFileName(&ofn))
			{
				// 如果之前有打开的文件，先关闭
				if (g_stuMap.pData)
				{
					UnMappingFile(g_stuMap);
				}

				// 打开文件并解析
				char szAnsiFile[MAX_PATH];
				WideCharToMultiByte(CP_ACP, 0, szFile, -1, szAnsiFile, MAX_PATH, NULL, NULL);
				if (MappingFile(szAnsiFile, g_stuMap))
				{
					try {
						FILE_TYPE emType = CFileBase::GuessFileType((PBYTE)g_stuMap.pData);
						if (emType == FILE_TYPE::PE)
						{
							if (g_pPEFile) {
								g_pPEFile->UnInit();
								delete g_pPEFile;
							}
							g_pPEFile = new CPEFile();
							if (g_pPEFile && g_pPEFile->Init((PBYTE)g_stuMap.pData, g_stuMap.dwFileSize))
							{
								DisplayPEInfo();
							}
							else {
								if (g_pPEFile) {
									delete g_pPEFile;
									g_pPEFile = NULL;
								}
								MessageBoxA(hwnd, "Failed to initialize PE file", "Error", MB_OK | MB_ICONERROR);
							}
						}
						else {
							MessageBoxA(hwnd, "Selected file is not a PE file", "Error", MB_OK | MB_ICONERROR);
						}
					} catch (...) {
						if (g_pPEFile) {
							delete g_pPEFile;
							g_pPEFile = NULL;
						}
						MessageBoxA(hwnd, "Error occurred while processing PE file", "Error", MB_OK | MB_ICONERROR);
					}
				}
				else {
					MessageBoxA(hwnd, "Failed to open file", "Error", MB_OK | MB_ICONERROR);
				}
			}
		}
		break;

		case ID_EXPORT_UNDECORATE:
		{
			// 获取选中的项
			int iItem = ListView_GetNextItem(g_hExportListView, -1, LVNI_SELECTED);
			if (iItem >= 0)
			{
				// 获取函数名
				WCHAR szFuncName[MAX_PATH] = {0};
				LVITEM lvi = {0};
				lvi.mask = LVIF_TEXT;
				lvi.iItem = iItem;
				lvi.iSubItem = 1;  // 函数名称列
				lvi.pszText = szFuncName;
				lvi.cchTextMax = MAX_PATH;
				ListView_GetItem(g_hExportListView, &lvi);

				// 转换为ANSI
				char szAnsiFuncName[MAX_PATH] = {0};
				WideCharToMultiByte(CP_ACP, 0, szFuncName, -1, szAnsiFuncName, MAX_PATH, NULL, NULL);

				// 使用dbghelp转换函数名
				char szUndecoratedName[MAX_PATH] = {0};
				if (UnDecorateSymbolName(szAnsiFuncName, szUndecoratedName, MAX_PATH, UNDNAME_COMPLETE))
				{
					// 转换回Unicode
					WCHAR szUndecoratedWName[MAX_PATH] = {0};
					MultiByteToWideChar(CP_ACP, 0, szUndecoratedName, -1, szUndecoratedWName, MAX_PATH);

					// 保存转换后的名称
					g_exportItems[iItem].decoratedName = szUndecoratedWName;
					g_exportItems[iItem].isDecorated = true;

					// 更新列表项
					lvi.pszText = szUndecoratedWName;
					ListView_SetItem(g_hExportListView, &lvi);
				}
				else
				{
					MessageBoxW(hwnd, L"无法转换函数名称", L"错误", MB_OK | MB_ICONERROR);
				}
			}
		}
		break;

		case ID_EXPORT_DECORATE:
		{
			// 获取选中的项
			int iItem = ListView_GetNextItem(g_hExportListView, -1, LVNI_SELECTED);
			if (iItem >= 0)
			{
				// 更新列表项为原始名称
				LVITEM lvi = {0};
				lvi.mask = LVIF_TEXT;
				lvi.iItem = iItem;
				lvi.iSubItem = 1;  // 函数名称列
				lvi.pszText = const_cast<LPWSTR>(g_exportItems[iItem].originalName.c_str());
				ListView_SetItem(g_hExportListView, &lvi);

				// 更新状态
				g_exportItems[iItem].isDecorated = false;
			}
		}
		break;

		case ID_EXPORT_SEARCH:
		{
			if (HIWORD(wParam) == EN_CHANGE)
			{
				WCHAR szSearchText[MAX_PATH] = {0};
				GetWindowText(g_hExportSearch, szSearchText, MAX_PATH);
				SearchExportTable(szSearchText);
			}
		}
		break;

		case ID_IMPORT_SEARCH:
		{
			if (HIWORD(wParam) == EN_CHANGE)
			{
				WCHAR szSearchText[MAX_PATH] = {0};
				GetWindowText(g_hImportSearch, szSearchText, MAX_PATH);
				SearchImportTable(szSearchText);
			}
		}
		break;
		}
		break;

	case WM_NOTIFY:
	{
		LPNMHDR lpnmhdr = (LPNMHDR)lParam;
		switch (lpnmhdr->code)
		{
		case TVN_SELCHANGED:
		{
			LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;
			switch (pnmtv->itemNew.lParam)
			{
			case 1: DisplayPEInfo(); break;
			case 2: DisplayExportTable(); break;
			case 3: DisplayImportTable(); break;
			case 4: DisplayDependencies(); break;
			}
		}
		break;

		case NM_RCLICK:
		{
			if (lpnmhdr->idFrom == ID_EXPORT_LISTVIEW)
			{
				LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
				if (lpnmia->iItem >= 0)
				{
					// 创建右键菜单
					HMENU hMenu = CreatePopupMenu();
					
					// 根据当前状态添加菜单项
					if (!g_exportItems[lpnmia->iItem].isDecorated)
					{
						AppendMenu(hMenu, MF_STRING, ID_EXPORT_UNDECORATE, L"转换为友好名称");
					}
					else
					{
						AppendMenu(hMenu, MF_STRING, ID_EXPORT_DECORATE, L"转换回原始名称");
					}

					// 获取鼠标位置
					POINT pt;
					GetCursorPos(&pt);

					// 显示菜单
					TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
					DestroyMenu(hMenu);
				}
			}
		}
		break;

		case NM_DBLCLK:
		{
			if (lpnmhdr->idFrom == ID_DEPENDENCY_LISTVIEW)
			{
				LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
				if (lpnmia->iItem >= 0)
				{
					// 获取选中的DLL名称
					WCHAR szDllName[MAX_PATH] = {0};
					LVITEM lvi = {0};
					lvi.mask = LVIF_TEXT;
					lvi.iItem = lpnmia->iItem;
					lvi.iSubItem = 0;
					lvi.pszText = szDllName;
					lvi.cchTextMax = MAX_PATH;
					ListView_GetItem(g_hDependencyListView, &lvi);

					// 搜索DLL文件
					WCHAR szFullPath[MAX_PATH] = {0};
					if (SearchDllFile(szDllName, szFullPath, MAX_PATH))
					{
						// 如果之前有打开的文件，先关闭
						if (g_stuMap.pData)
						{
							UnMappingFile(g_stuMap);
						}

						// 打开文件并解析
						char szAnsiFile[MAX_PATH];
						WideCharToMultiByte(CP_ACP, 0, szFullPath, -1, szAnsiFile, MAX_PATH, NULL, NULL);
						if (MappingFile(szAnsiFile, g_stuMap))
						{
							try {
								FILE_TYPE emType = CFileBase::GuessFileType((PBYTE)g_stuMap.pData);
								if (emType == FILE_TYPE::PE)
								{
									if (g_pPEFile) {
										g_pPEFile->UnInit();
										delete g_pPEFile;
									}
									g_pPEFile = new CPEFile();
									if (g_pPEFile && g_pPEFile->Init((PBYTE)g_stuMap.pData, g_stuMap.dwFileSize))
									{
										DisplayPEInfo();
									}
									else {
										if (g_pPEFile) {
											delete g_pPEFile;
											g_pPEFile = NULL;
										}
										MessageBoxA(hwnd, "Failed to initialize PE file", "Error", MB_OK | MB_ICONERROR);
									}
								}
								else {
									MessageBoxA(hwnd, "Selected file is not a PE file", "Error", MB_OK | MB_ICONERROR);
								}
							} catch (...) {
								if (g_pPEFile) {
									delete g_pPEFile;
									g_pPEFile = NULL;
								}
								MessageBoxA(hwnd, "Error occurred while processing PE file", "Error", MB_OK | MB_ICONERROR);
							}
						}
						else {
							MessageBoxA(hwnd, "Failed to open file", "Error", MB_OK | MB_ICONERROR);
						}
					}
					else
					{
						MessageBoxW(hwnd, L"找不到指定的DLL文件", L"错误", MB_OK | MB_ICONERROR);
					}
				}
			}
		}
		break;
		}
	}
	break;

	case WM_DESTROY:
		if (g_pPEFile) delete g_pPEFile;
		if (g_stuMap.pData) UnMappingFile(g_stuMap);  // 程序退出时清理文件映射
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;
}

void InitTreeView(HWND hwndParent)
{
	// 创建图像列表
	HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 5, 5);
	
	// 加载图标并添加到图像列表
	HICON hIconFile = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_FILE));
	HICON hIconPE = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_PE));
	HICON hIconExport = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_EXPORT));
	HICON hIconImport = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_IMPORT));

	// 添加图标到图像列表
	ImageList_AddIcon(hImageList, hIconFile);
	ImageList_AddIcon(hImageList, hIconPE);
	ImageList_AddIcon(hImageList, hIconExport);
	ImageList_AddIcon(hImageList, hIconImport);

	// 创建树形控件
	g_hTreeView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, L"",
		WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_FULLROWSELECT | TVS_SHOWSELALWAYS,
		10, 10, 250, 700,
		hwndParent, (HMENU)ID_TREEVIEW, GetModuleHandle(NULL), NULL);

	// 设置树形控件的图像列表
	TreeView_SetImageList(g_hTreeView, hImageList, TVSIL_NORMAL);

	// 添加树形项
	TVINSERTSTRUCT tvInsert;
	tvInsert.hParent = TVI_ROOT;
	tvInsert.hInsertAfter = TVI_LAST;
	tvInsert.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

	WCHAR szText[MAX_PATH];
	wcscpy_s(szText, L"PE文件信息");
	tvInsert.item.pszText = szText;
	tvInsert.item.lParam = 1;
	tvInsert.item.iImage = 1;      // 使用PE图标
	tvInsert.item.iSelectedImage = 1;
	TreeView_InsertItem(g_hTreeView, &tvInsert);

	wcscpy_s(szText, L"导出表");
	tvInsert.item.pszText = szText;
	tvInsert.item.lParam = 2;
	tvInsert.item.iImage = 2;      // 使用导出表图标
	tvInsert.item.iSelectedImage = 2;
	TreeView_InsertItem(g_hTreeView, &tvInsert);

	wcscpy_s(szText, L"导入表");
	tvInsert.item.pszText = szText;
	tvInsert.item.lParam = 3;
	tvInsert.item.iImage = 3;      // 使用导入表图标
	tvInsert.item.iSelectedImage = 3;
	TreeView_InsertItem(g_hTreeView, &tvInsert);

	wcscpy_s(szText, L"依赖库");
	tvInsert.item.pszText = szText;
	tvInsert.item.lParam = 4;
	tvInsert.item.iImage = 4;      // 使用依赖库图标
	tvInsert.item.iSelectedImage = 4;
	TreeView_InsertItem(g_hTreeView, &tvInsert);

	// 清理图标资源
	DestroyIcon(hIconFile);
	DestroyIcon(hIconPE);
	DestroyIcon(hIconExport);
	DestroyIcon(hIconImport);

	// 创建编辑控件用于显示详细信息
	g_hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
		WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
		270, 10, 740, 700,
		hwndParent, (HMENU)ID_EDIT, GetModuleHandle(NULL), NULL);

	// 创建列表控件
	g_hListView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
		WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS,
		270, 10, 740, 700,
		hwndParent, (HMENU)ID_LISTVIEW, GetModuleHandle(NULL), NULL);

	// 添加列表控件列
	LVCOLUMN lvc = {0};
	lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;

	// 导入表列
	lvc.iSubItem = 0;
	lvc.cx = 200;
	lvc.pszText = const_cast<LPWSTR>(L"DLL名称");
	ListView_InsertColumn(g_hListView, 0, &lvc);

	lvc.iSubItem = 1;
	lvc.cx = 300;
	lvc.pszText = const_cast<LPWSTR>(L"函数名称");
	ListView_InsertColumn(g_hListView, 1, &lvc);

	lvc.iSubItem = 2;
	lvc.cx = 100;
	lvc.pszText = const_cast<LPWSTR>(L"序号");
	ListView_InsertColumn(g_hListView, 2, &lvc);

	// 创建PE信息列表控件
	g_hPEInfoListView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
		WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS,
		270, 10, 740, 700,
		hwndParent, (HMENU)ID_PEINFO_LISTVIEW, GetModuleHandle(NULL), NULL);

	// PE信息列
	lvc.iSubItem = 0;
	lvc.cx = 250;
	lvc.pszText = const_cast<LPWSTR>(L"属性");
	ListView_InsertColumn(g_hPEInfoListView, 0, &lvc);

	lvc.iSubItem = 1;
	lvc.cx = 470;
	lvc.pszText = const_cast<LPWSTR>(L"值");
	ListView_InsertColumn(g_hPEInfoListView, 1, &lvc);

	// 创建导出表列表控件
	g_hExportListView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
		WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS,
		270, 10, 740, 700,
		hwndParent, (HMENU)ID_EXPORT_LISTVIEW, GetModuleHandle(NULL), NULL);

	// 导出表列
	lvc.iSubItem = 0;
	lvc.cx = 150;
	lvc.pszText = const_cast<LPWSTR>(L"序号");
	ListView_InsertColumn(g_hExportListView, 0, &lvc);

	lvc.iSubItem = 1;
	lvc.cx = 570;
	lvc.pszText = const_cast<LPWSTR>(L"函数名称");
	ListView_InsertColumn(g_hExportListView, 1, &lvc);

	// 创建依赖库列表控件
	g_hDependencyListView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
		WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS,
		270, 10, 740, 700,
		hwndParent, (HMENU)ID_DEPENDENCY_LISTVIEW, GetModuleHandle(NULL), NULL);

	// 依赖库列表列
	lvc.iSubItem = 0;
	lvc.cx = 740;
	lvc.pszText = const_cast<LPWSTR>(L"依赖库名称");
	ListView_InsertColumn(g_hDependencyListView, 0, &lvc);

	// 创建导出表搜索框
	g_hExportSearch = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
		WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
		270, 10, 740, 25,
		hwndParent, (HMENU)ID_EXPORT_SEARCH, GetModuleHandle(NULL), NULL);

	// 创建导入表搜索框
	g_hImportSearch = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
		WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
		270, 10, 740, 25,
		hwndParent, (HMENU)ID_IMPORT_SEARCH, GetModuleHandle(NULL), NULL);

	// 默认隐藏搜索框
	ShowWindow(g_hExportSearch, SW_HIDE);
	ShowWindow(g_hImportSearch, SW_HIDE);

	// 默认隐藏所有列表控件
	ShowWindow(g_hListView, SW_HIDE);
	ShowWindow(g_hPEInfoListView, SW_HIDE);
	ShowWindow(g_hExportListView, SW_HIDE);
	ShowWindow(g_hDependencyListView, SW_HIDE);

	// 添加菜单
	HMENU hMenu = CreateMenu();
	HMENU hFileMenu = CreatePopupMenu();
	
	// 创建菜单项图标
	HICON hIconOpen = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_FILE));
	MENUITEMINFO mii = {0};
	mii.cbSize = sizeof(MENUITEMINFO);
	mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID;
	mii.wID = ID_FILE_OPEN;
	
	// 使用非const字符串
	WCHAR szMenuText[] = L"打开文件";
	mii.dwTypeData = szMenuText;
	
	// 创建位图
	HDC hdc = GetDC(NULL);
	HDC hdcMem = CreateCompatibleDC(hdc);
	HBITMAP hBitmap = CreateCompatibleBitmap(hdc, 16, 16);
	HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);
	
	// 绘制图标到位图
	DrawIconEx(hdcMem, 0, 0, hIconOpen, 16, 16, 0, NULL, DI_NORMAL);
	
	// 设置菜单项
	mii.hbmpItem = hBitmap;
	InsertMenuItem(hFileMenu, 0, TRUE, &mii);
	
	// 清理资源
	SelectObject(hdcMem, hOldBitmap);
	DeleteObject(hBitmap);
	DeleteDC(hdcMem);
	ReleaseDC(NULL, hdc);
	DestroyIcon(hIconOpen);
	
	// 使用非const字符串
	WCHAR szFileMenuText[] = L"文件";
	AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, szFileMenuText);
	SetMenu(hwndParent, hMenu);

	// 设置列表控件样式
	DWORD dwStyle = ListView_GetExtendedListViewStyle(g_hListView);
	dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER;
	ListView_SetExtendedListViewStyle(g_hListView, dwStyle);

	dwStyle = ListView_GetExtendedListViewStyle(g_hPEInfoListView);
	dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER;
	ListView_SetExtendedListViewStyle(g_hPEInfoListView, dwStyle);

	dwStyle = ListView_GetExtendedListViewStyle(g_hExportListView);
	dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER;
	ListView_SetExtendedListViewStyle(g_hExportListView, dwStyle);

	dwStyle = ListView_GetExtendedListViewStyle(g_hDependencyListView);
	dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER;
	ListView_SetExtendedListViewStyle(g_hDependencyListView, dwStyle);
}

void DisplayPEInfo()
{
	if (!g_pPEFile) return;
	
	// 显示PE信息列表控件，隐藏其他控件
	ShowWindow(g_hPEInfoListView, SW_SHOW);
	ShowWindow(g_hEdit, SW_HIDE);
	ShowWindow(g_hListView, SW_HIDE);
	ShowWindow(g_hExportListView, SW_HIDE);
	ShowWindow(g_hDependencyListView, SW_HIDE);
	
	// 清空列表
	ListView_DeleteAllItems(g_hPEInfoListView);
	
	std::stringstream ss;
	std::streambuf* old = std::cout.rdbuf(ss.rdbuf());
	try {
		g_pPEFile->PrintFileInfo("");
	} catch (...) {
		std::cout.rdbuf(old);
		MessageBox(NULL, L"获取PE信息失败", L"错误", MB_OK | MB_ICONERROR);
		return;
	}
	std::cout.rdbuf(old);

	// 解析输出并添加到列表
	std::string line;
	int itemIndex = 0;
	while (std::getline(ss, line)) {
		// 跳过空行
		if (line.empty()) continue;

		// 查找冒号位置
		size_t colonPos = line.find(':');
		if (colonPos != std::string::npos) {
			// 属性名和值
			std::string name = line.substr(0, colonPos);
			std::string value = line.substr(colonPos + 1);

			// 转换为宽字符串
			int nameLen = MultiByteToWideChar(CP_ACP, 0, name.c_str(), -1, NULL, 0);
			int valueLen = MultiByteToWideChar(CP_ACP, 0, value.c_str(), -1, NULL, 0);
			
			std::vector<wchar_t> nameWstr(nameLen);
			std::vector<wchar_t> valueWstr(valueLen);
			
			MultiByteToWideChar(CP_ACP, 0, name.c_str(), -1, nameWstr.data(), nameLen);
			MultiByteToWideChar(CP_ACP, 0, value.c_str(), -1, valueWstr.data(), valueLen);

			// 添加到列表
			LVITEM lvi = { 0 };
			lvi.mask = LVIF_TEXT;
			lvi.iItem = itemIndex;
			
			lvi.iSubItem = 0;
			lvi.pszText = nameWstr.data();
			ListView_InsertItem(g_hPEInfoListView, &lvi);

			lvi.iSubItem = 1;
			lvi.pszText = valueWstr.data();
			ListView_SetItem(g_hPEInfoListView, &lvi);

			itemIndex++;
		}
	}
}

void DisplayExportTable()
{
	if (!g_pPEFile) return;
	
	// 显示导出表列表控件和搜索框，隐藏其他控件
	ShowWindow(g_hExportListView, SW_SHOW);
	ShowWindow(g_hExportSearch, SW_SHOW);
	ShowWindow(g_hEdit, SW_HIDE);
	ShowWindow(g_hListView, SW_HIDE);
	ShowWindow(g_hPEInfoListView, SW_HIDE);
	ShowWindow(g_hDependencyListView, SW_HIDE);
	ShowWindow(g_hImportSearch, SW_HIDE);
	
	// 清空列表和缓存
	ListView_DeleteAllItems(g_hExportListView);
	g_exportItems.clear();
	
	std::stringstream ss;
	std::streambuf* old = std::cout.rdbuf(ss.rdbuf());
	try {
		g_pPEFile->PrintPEExportTable();
	} catch (...) {
		std::cout.rdbuf(old);
		MessageBox(NULL, L"获取导出表信息失败", L"错误", MB_OK | MB_ICONERROR);
		return;
	}
	std::cout.rdbuf(old);

	// 解析输出并添加到列表
	std::string line;
	int itemIndex = 0;
	while (std::getline(ss, line)) {
		// 跳过空行和标题行
		if (line.empty() || line == "Exports:") continue;

		// 查找制表符位置
		size_t tabPos = line.find('\t');
		if (tabPos != std::string::npos) {
			// 序号和函数名
			std::string ordinal = line.substr(0, tabPos);
			std::string funcName = line.substr(tabPos + 1);

			// 检查序号是否为空
			if (ordinal.empty()) {
				continue;
			}

			// 转换为宽字符串
			std::wstring ordinalWstr;
			try {
				// 将十六进制字符串转换为数字
				WORD ordinalNum = static_cast<WORD>(std::stoul(ordinal, nullptr, 16));
				ordinalWstr = std::to_wstring(ordinalNum);
			} catch (...) {
				// 如果转换失败，直接使用原始字符串
				int ordinalLen = MultiByteToWideChar(CP_ACP, 0, ordinal.c_str(), -1, NULL, 0);
				std::vector<wchar_t> ordinalWstrTemp(ordinalLen);
				MultiByteToWideChar(CP_ACP, 0, ordinal.c_str(), -1, ordinalWstrTemp.data(), ordinalLen);
				ordinalWstr = ordinalWstrTemp.data();
			}

			int funcNameLen = MultiByteToWideChar(CP_ACP, 0, funcName.c_str(), -1, NULL, 0);
			std::vector<wchar_t> funcNameWstr(funcNameLen);
			MultiByteToWideChar(CP_ACP, 0, funcName.c_str(), -1, funcNameWstr.data(), funcNameLen);

			// 保存导出项信息
			ExportItem item;
			item.originalName = funcNameWstr.data();
			item.isDecorated = false;
			g_exportItems.push_back(item);

			// 添加到列表
			LVITEM lvi = { 0 };
			lvi.mask = LVIF_TEXT;
			lvi.iItem = itemIndex;
			
			lvi.iSubItem = 0;
			lvi.pszText = const_cast<LPWSTR>(ordinalWstr.c_str());
			ListView_InsertItem(g_hExportListView, &lvi);

			lvi.iSubItem = 1;
			lvi.pszText = funcNameWstr.data();
			ListView_SetItem(g_hExportListView, &lvi);

			itemIndex++;
		}
	}
}

void DisplayImportTable()
{
	if (!g_pPEFile) return;
	
	// 显示导入表列表控件和搜索框，隐藏其他控件
	ShowWindow(g_hListView, SW_SHOW);
	ShowWindow(g_hImportSearch, SW_SHOW);
	ShowWindow(g_hEdit, SW_HIDE);
	ShowWindow(g_hPEInfoListView, SW_HIDE);
	ShowWindow(g_hExportListView, SW_HIDE);
	ShowWindow(g_hDependencyListView, SW_HIDE);
	ShowWindow(g_hExportSearch, SW_HIDE);
	
	// 清空列表控件
	ListView_DeleteAllItems(g_hListView);

	// 获取导入表信息
	std::vector<IMPORT_DLL_INFO> importDlls;
	if (!g_pPEFile->GetImportTable(importDlls))
	{
		MessageBox(NULL, L"获取导入表信息失败", L"错误", MB_OK | MB_ICONERROR);
		return;
	}

	// 收集所有导入函数信息并按序号排序
	struct ImportItem {
		std::wstring dllName;
		std::wstring funcName;
		WORD ordinal;
	};
	std::vector<ImportItem> importItems;

	for (const auto& dllInfo : importDlls)
	{
		for (const auto& funcInfo : dllInfo.vecFuncs)
		{
			ImportItem item;
			item.dllName = dllInfo.szDllName;
			item.funcName = funcInfo.szFuncName;
			item.ordinal = funcInfo.wOrdinal;
			importItems.push_back(item);
		}
	}

	// 按序号排序
	std::sort(importItems.begin(), importItems.end(),
		[](const ImportItem& a, const ImportItem& b) {
			return a.ordinal < b.ordinal;
		});

	// 显示导入表信息
	int itemIndex = 0;
	for (const auto& item : importItems)
	{
		LVITEM lvi = { 0 };
		lvi.mask = LVIF_TEXT;
		lvi.iItem = itemIndex;
		
		// DLL名称
		lvi.iSubItem = 0;
		lvi.pszText = const_cast<LPWSTR>(item.dllName.c_str());
		ListView_InsertItem(g_hListView, &lvi);

		// 函数名称
		lvi.iSubItem = 1;
		lvi.pszText = const_cast<LPWSTR>(item.funcName.c_str());
		ListView_SetItem(g_hListView, &lvi);

		// 序号
		lvi.iSubItem = 2;
		std::wstring ordinalStr = std::to_wstring(item.ordinal);
		lvi.pszText = const_cast<LPWSTR>(ordinalStr.c_str());
		ListView_SetItem(g_hListView, &lvi);

		itemIndex++;
	}
}

void DisplayDependencies()
{
	if (!g_pPEFile) return;
	
	// 显示依赖库列表控件，隐藏其他控件
	ShowWindow(g_hDependencyListView, SW_SHOW);
	ShowWindow(g_hEdit, SW_HIDE);
	ShowWindow(g_hListView, SW_HIDE);
	ShowWindow(g_hPEInfoListView, SW_HIDE);
	ShowWindow(g_hExportListView, SW_HIDE);
	
	// 清空列表
	ListView_DeleteAllItems(g_hDependencyListView);
	
	// 获取导入表信息
	std::vector<IMPORT_DLL_INFO> importDlls;
	if (!g_pPEFile->GetImportTable(importDlls))
	{
		MessageBox(NULL, L"获取依赖库信息失败", L"错误", MB_OK | MB_ICONERROR);
		return;
	}

	// 显示依赖库信息
	int itemIndex = 0;
	for (const auto& dllInfo : importDlls)
	{
		LVITEM lvi = { 0 };
		lvi.mask = LVIF_TEXT;
		lvi.iItem = itemIndex;
		
		// DLL名称
		lvi.iSubItem = 0;
		lvi.pszText = const_cast<LPWSTR>(dllInfo.szDllName.c_str());
		ListView_InsertItem(g_hDependencyListView, &lvi);

		itemIndex++;
	}
}

// 添加搜索DLL文件的函数
BOOL SearchDllFile(const WCHAR* szDllName, WCHAR* szFullPath, DWORD dwMaxPath)
{
	// 初始化符号搜索路径
	SymInitialize(GetCurrentProcess(), NULL, TRUE);

	// 获取系统目录
	WCHAR szSystemDir[MAX_PATH] = {0};
	GetSystemDirectory(szSystemDir, MAX_PATH);

	// 获取Windows目录
	WCHAR szWindowsDir[MAX_PATH] = {0};
	GetWindowsDirectory(szWindowsDir, MAX_PATH);

	// 定义搜索路径
	const WCHAR* szSearchPaths[] = {
		szSystemDir,
		szWindowsDir,
		L"C:\\Windows\\SysWOW64",  // 32位系统DLL目录
		L"C:\\Windows\\System32",  // 64位系统DLL目录
		NULL
	};

	// 在搜索路径中查找DLL
	for (int i = 0; szSearchPaths[i] != NULL; i++)
	{
		wcscpy_s(szFullPath, dwMaxPath, szSearchPaths[i]);
		wcscat_s(szFullPath, dwMaxPath, L"\\");
		wcscat_s(szFullPath, dwMaxPath, szDllName);

		if (GetFileAttributes(szFullPath) != INVALID_FILE_ATTRIBUTES)
		{
			return TRUE;
		}
	}

	// 使用dbghelp搜索
	char szSymbolPath[MAX_PATH] = {0};
	if (SymGetSearchPath(GetCurrentProcess(), szSymbolPath, MAX_PATH))
	{
		char* szContext = NULL;
		char* szPath = strtok_s(szSymbolPath, ";", &szContext);
		while (szPath != NULL)
		{
			// 将ANSI路径转换为Unicode
			WCHAR szUnicodePath[MAX_PATH] = {0};
			MultiByteToWideChar(CP_ACP, 0, szPath, -1, szUnicodePath, MAX_PATH);

			wcscpy_s(szFullPath, dwMaxPath, szUnicodePath);
			wcscat_s(szFullPath, dwMaxPath, L"\\");
			wcscat_s(szFullPath, dwMaxPath, szDllName);

			if (GetFileAttributes(szFullPath) != INVALID_FILE_ATTRIBUTES)
			{
				return TRUE;
			}

			szPath = strtok_s(NULL, ";", &szContext);
		}
	}

	return FALSE;
}

// 添加搜索函数
void SearchExportTable(const WCHAR* szSearchText)
{
	if (!g_pPEFile) return;
	
	// 清空列表
	ListView_DeleteAllItems(g_hExportListView);
	
	// 转换为小写搜索文本
	std::wstring searchText = szSearchText;
	std::transform(searchText.begin(), searchText.end(), searchText.begin(), ::tolower);
	
	// 遍历导出项并匹配
	int itemIndex = 0;
	for (size_t i = 0; i < g_exportItems.size(); i++)
	{
		const auto& item = g_exportItems[i];
		std::wstring displayName = item.isDecorated ? item.decoratedName : item.originalName;
		std::wstring lowerDisplayName = displayName;
		std::transform(lowerDisplayName.begin(), lowerDisplayName.end(), lowerDisplayName.begin(), ::tolower);
		
		// 如果搜索文本为空或包含在显示名称中，则显示该项
		if (searchText.empty() || lowerDisplayName.find(searchText) != std::wstring::npos)
		{
			// 获取序号
			WCHAR szOrdinal[MAX_PATH] = {0};
			LVITEM lvi = {0};
			lvi.mask = LVIF_TEXT;
			lvi.iItem = itemIndex;
			lvi.iSubItem = 0;
			lvi.pszText = szOrdinal;
			lvi.cchTextMax = MAX_PATH;
			ListView_GetItem(g_hExportListView, &lvi);
			
			// 添加匹配项
			lvi.pszText = const_cast<LPWSTR>(displayName.c_str());
			ListView_InsertItem(g_hExportListView, &lvi);
			
			itemIndex++;
		}
	}
}

void SearchImportTable(const WCHAR* szSearchText)
{
	if (!g_pPEFile) return;
	
	// 清空列表
	ListView_DeleteAllItems(g_hListView);
	
	// 转换为小写搜索文本
	std::wstring searchText = szSearchText;
	std::transform(searchText.begin(), searchText.end(), searchText.begin(), ::tolower);
	
	// 获取导入表信息
	std::vector<IMPORT_DLL_INFO> importDlls;
	if (!g_pPEFile->GetImportTable(importDlls))
	{
		return;
	}
	
	// 收集所有导入函数信息并按序号排序
	struct ImportItem {
		std::wstring dllName;
		std::wstring funcName;
		WORD ordinal;
	};
	std::vector<ImportItem> importItems;
	
	for (const auto& dllInfo : importDlls)
	{
		for (const auto& funcInfo : dllInfo.vecFuncs)
		{
			ImportItem item;
			item.dllName = dllInfo.szDllName;
			item.funcName = funcInfo.szFuncName;
			item.ordinal = funcInfo.wOrdinal;
			importItems.push_back(item);
		}
	}
	
	// 按序号排序
	std::sort(importItems.begin(), importItems.end(),
		[](const ImportItem& a, const ImportItem& b) {
			return a.ordinal < b.ordinal;
		});
	
	// 显示匹配的导入表信息
	int itemIndex = 0;
	for (const auto& item : importItems)
	{
		// 转换为小写进行比较
		std::wstring lowerFuncName = item.funcName;
		std::transform(lowerFuncName.begin(), lowerFuncName.end(), lowerFuncName.begin(), ::tolower);
		
		// 如果搜索文本为空或包含在函数名中，则显示该项
		if (searchText.empty() || lowerFuncName.find(searchText) != std::wstring::npos)
		{
			LVITEM lvi = { 0 };
			lvi.mask = LVIF_TEXT;
			lvi.iItem = itemIndex;
			
			// DLL名称
			lvi.iSubItem = 0;
			lvi.pszText = const_cast<LPWSTR>(item.dllName.c_str());
			ListView_InsertItem(g_hListView, &lvi);
			
			// 函数名称
			lvi.iSubItem = 1;
			lvi.pszText = const_cast<LPWSTR>(item.funcName.c_str());
			ListView_SetItem(g_hListView, &lvi);
			
			// 序号
			lvi.iSubItem = 2;
			std::wstring ordinalStr = std::to_wstring(item.ordinal);
			lvi.pszText = const_cast<LPWSTR>(ordinalStr.c_str());
			ListView_SetItem(g_hListView, &lvi);
			
			itemIndex++;
		}
	}
}

// 运行程序: Ctrl + F5 或调试 >"开始执行(不调试)"菜单
// 调试程序: F5 或调试 >"开始调试"菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到">"项目">"添加新项"以创建新的代码文件，或转到">"项目">"添加现有项"以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到"文件">"打开">"项目"并选择 .sln 文件
